基于定位服务、地图服务实现运动轨迹绘制

您所在的位置:网站首页 map kit地图 基于定位服务、地图服务实现运动轨迹绘制

基于定位服务、地图服务实现运动轨迹绘制

2023-12-13 15:05| 来源: 网络整理| 查看: 265

业务场景介绍

在打车、运动、导航类应用中,基于当前位置信息在地图上进行展示,并根据位置信息的变化,绘制运动轨迹的场景,现在非常流行。直观的运动轨迹展示,可以给用户带来更好的用户体验。

通过本篇Codelab,我们将基于华为定位服务(Location Kit)、华为地图服务(Map Kit),以用户跑步运动的应用场景为例,详细的为开发者讲解实现运动轨迹这个业务场景的开发过程。

您将建立什么

在这个Codelab中,您将实现通过华为定位服务、地图服务服务实现:

华为定位服务,获取当前的位置信息,实时获取位置信息更新; 华为地图服务,根据定位信息展示当前位置地图,并通过实时位置信息绘制运动轨迹; 使用定位服务的模拟定位能力,进行运动轨迹重现。 您将会学到什么 如何在AppGallery Connect上创建应用。 如何开通定位、地图服务。 如何集成华为定位服务,如何获取实时位置信息,如何使用模拟定位模式。 如何集成地图服务, 如何展示地图,如何在地图上绘制运动轨迹,如何在地图上绘制图标。 您需要什么 硬件要求 开发计算机(台式机或笔记本电脑),运行Windows 10操作系统。 预装了HMS Core(APK)5.1.0及以上版本的HUAWEI手机一部,用于真机调试运行demo。 软件要求 Android Studio 3.X及以上。 JDK 1.7 及以上。 SDK Platform 19及以上。 HMS Core(APK)5.1.0及以上版本。

集成HUAWEI HMS Core能力,需要完成以下准备工作

创建AGC应用 创建Android Studio工程 生成签名证书 生成签名证书指纹 配置签名证书指纹 添加应用包名并保存配置文件 配置Maven仓地址及AGC gradle插件 在Android Studio配置签名文件

具体操作,请按照《HUAWEI HMS Core集成准备》中详细说明来完成。

提示:需要通过注册成开发者才能完成集成准备中的操作。

华为定位服务和地图服务可以通过如下两种方式开通,具体开通实现如下:

方式一

在AppGallery Connect中选择"我的项目",在项目列表中选择创建的应用,在"项目设置"页面中选择"API管理"。

打开Location Kit、Map Kit服务。

方式二

在华为开发者联盟控制台中,在页面侧边栏,选择"HMS API服务"->"API库",并选择对应项目。

在"API库"中找到定位服务、地图服务。

进入卡片中,点击"启用"按钮,即可开通服务。

定位服务 地图服务 获取配置文件

打开华为开发者联盟AppGallery Connect选择"我的项目",在项目列表中选择创建的应用,在"项目设置"页面中选择"常规",并在项目数据存储位置点击设置按钮。

下载应用中的"agconnect-services.json"文件。

将 "agconnect-services.json"文件移至Android Studio开发工程应用模块的根目录。

配置HMS Core SDK依赖

打开项目级的build.gradle文件。

在"buildscript > repositories"中配置HMS Core SDK的Maven仓地址。 在"allprojects > repositories"中配置HMS Core SDK的Maven仓地址。 如果App中添加了"agconnect-services.json"文件则需要在"buildscript > dependencies"中增加agcp配置。

项目级build.gradle中代码如下:

buildscript { ext.kotlin_version = "1.4.10" repositories { google() jcenter() maven {url 'http://developer.huawei.com/repo/'} } dependencies { classpath "com.android.tools.build:gradle:4.1.1" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath 'com.huawei.agconnect:agcp:1.4.0.300' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } } allprojects { repositories { google() jcenter() maven {url 'http://developer.huawei.com/repo/'} } }

打开应用级的build.gradle文件。

在"dependencies"中添加定位服务和地图服务依赖

dependencies { implementation 'com.huawei.hms:location:{version}' implementation 'com.huawei.hms:maps:{version}' }

提示:其中集成的{version}请替换成SDK版本,最新版本链接:定位服务:版本更新说明。地图服务:版本更新说明。

点击Sync Now 同步工程。

配置混淆脚本

提示:如果开发者有使用到代码混淆功能,请配置混淆配置文件避免HMS Core SDK被混淆导致功能异常。

1.打开Android Studio工程的混淆配置文件proguard-rules.pro。2.加入混淆配置。

-ignorewarnings -keepattributes *Annotation* -keepattributes Exceptions -keepattributes InnerClasses -keepattributes Signature -keepattributes SourceFile,LineNumberTable -keep class com.huawei.hianalytics.**{*;} -keep class com.huawei.updatesdk.**{*;} -keep class com.huawei.hms.**{*;}

3.如果开发者使用了AndResGuard,需要在混淆配置文件中加入AndResGuard允许清单。

"R.string.hms*", "R.string.connect_server_fail_prompt_toast", "R.string.getting_message_fail_prompt_toast", "R.string.no_available_network_prompt_toast", "R.string.third_app_*", "R.string.upsdk_*", "R.layout.hms*", "R.layout.upsdk_*", "R.drawable.upsdk*", "R.color.upsdk*", "R.dimen.upsdk*", "R.style.upsdk*", "R.string.agc*" 地图服务说明

地图服务(Map Kit)给您提供一套地图开发调用的SDK,地图数据覆盖超过200个国家和地区,支持一百多种语言,方便您轻松地在应用中集成地图相关的功能,全方位提升用户体验。

注意: 地图服务暂不支持中国大陆。

我们将使用Map Kit,来绘制一个基础地图。

地图容器

目前华为地图SDK支持的地图容器有两种,SupportMapFragment、MapView:

MapView是Android View类的子类,允许您将地图放置在Android视图中。与SupportMapFragment非常相似,MapView充当地图的容器,通过HuaweiMap对象展示核心地图功能。在常规地图交互模式下调用API时,MapView类的使用者必须在对应的Activity/Fragment的方法中调用以下方法:onCreate(),onStart(),onResume(),onPause(),onStop(),onDestroy(),onSaveInstanceState(Bundle outState)和onLowMemory()。

在本篇Codelab中,我们使用MapView来创建一个Map示例。

1. 创建MapView布局

我们先创建一个MapActivity,在Activity的布局文件中添加一个MapView,并通过XML文件设置Map的属性。

布局代码

2. 实现回调接口并声明需要的对象

MapActivity中,需要实现OnMapReadyCallback接口,并声明MapView对象、HuaweiMap对象、地图上绘制折线所用到的PolylineOptions对象,。

Java代码

public class MapActivity extends AppCompatActivity implements OnMapReadyCallback { private MapView mMapView; private HuaweiMap mHwMap; private PolylineOptions mPolylineOptions; private LocationSource.OnLocationChangedListener mListener; }

Kotlin代码

class MapActivity : AppCompatActivity(), OnMapReadyCallback { private lateinit var mMapView: MapView private var mHwMap: HuaweiMap? = null private var mPolylineOptions: PolylineOptions? = null private var mListener: LocationSource.OnLocationChangedListener? = null } 3.创建MapView实例

在MapActivity的onCreate()方法中加载MapView,并使用getMapAsync()方法来注册回调方法。

Java代码

// init MapView mMapView = findViewById(R.id.hw_mapview); Bundle mapViewBundle = null; if (savedInstanceState != null) { mapViewBundle = savedInstanceState.getBundle(MAPVIEW_BUNDLE_KEY); } mMapView.onCreate(mapViewBundle); mMapView.getMapAsync(this);

Kotlin代码

// init MapView mMapView = findViewById(R.id.hw_mapview) var mapViewBundle: Bundle? = null if (savedInstanceState != null) { mapViewBundle = savedInstanceState.getBundle(MAPVIEW_BUNDLE_KEY) } mMapView.onCreate(mapViewBundle) mMapView.getMapAsync(this) 4.在OnMapReady回调中,获取HuaweiMap对象。

Java代码

@Override public void onMapReady(HuaweiMap huaweiMap) { mHwMap = huaweiMap; }

Kotlin代码

override fun onMapReady(huaweiMap: HuaweiMap?) { mHwMap = huaweiMap } 5.添加MapView的方法

实现onStart(),onResume(),onPause(),onStop(),onDestroy()和onLowMemory()方法中调用MapView对应的方法。。

Java代码

@Override protected void onStart() { super.onStart(); mMapView.onStart(); } @Override protected void onResume() { super.onResume(); mMapView.onResume(); } @Override protected void onPause() { super.onPause(); mMapView.onPause(); } @Override protected void onStop() { super.onStop(); mMapView.onStop(); } @Override protected void onDestroy() { super.onDestroy(); mMapView.onDestroy(); } @Override public void onLowMemory() { super.onLowMemory(); mMapView.onLowMemory(); }

Kotlin代码

companion object { private const val MAPVIEW_BUNDLE_KEY = "MapViewBundleKey" } override fun onStart() { super.onStart() mMapView.onStart() } override fun onResume() { super.onResume() mMapView.onResume() } override fun onPause() { super.onPause() mMapView.onPause() } override fun onStop() { super.onStop() mMapView.onStop() } override fun onDestroy() { super.onDestroy() mMapView.onDestroy() } override fun onLowMemory() { super.onLowMemory() mMapView.onLowMemory() }

至此基础地图我们已经创建完毕了,现在应用是这个样子的。

定位服务(Location Kit)采用GNSS、Wi-Fi、基站等多途径的混合定位模式进行定位,赋予应用开发者快速、精准地获取用户位置信息的能力,构建全球定位服务能力,助力您发展全球业务。当前定位服务的主要能力包含三个部分:融合定位、活动识别和地理围栏。本篇Codelab中,我们使用到了Location Kit的融合定位能力。

1. 指定应用权限,

提示:1.在Android Q版本中,如果您需要应用程序在后台执行时也具备持续定位能力,需要在Manifest文件中申请ACCESS_BACKGROUND_LOCATION权限2.本次Codelab使用了模拟定位功能,所以加入了ACCESS_MOCK_LOCATION权限。

2. 代码中动态申请一下权限(Android 6.0危险权限要求)

Java代码

// SDK when ((e as ApiException).statusCode) { LocationSettingsStatusCodes.RESOLUTION_REQUIRED -> try { val rae: ResolvableApiException = e as ResolvableApiException rae.startResolutionForResult(this@MapActivity, 0) } catch (sie: SendIntentException) { } } } } 5. 持续的获取位置信息

如果您希望应用可以持续获取设备位置,可以使用华为定位服务提供的requestLocationUpdates()接口。该接口通过调用您已经定义的LocationCallback类中onLocationResult()回调方法返回一个包含位置信息的LocationResult对象。

Java

private void requestLocationUpdate() { mLocationRequest = new LocationRequest(); mLocationRequest.setInterval(5000); mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); mLocationCallback = new LocationCallback() { @Override public void onLocationResult(LocationResult locationResult) { super.onLocationResult(locationResult); writeGpsData2Sdcard(locationResult.getLastLocation()); if (mIsRunning) { updateLocation(locationResult.getLastLocation()); } } @Override public void onLocationAvailability(LocationAvailability locationAvailability) { super.onLocationAvailability(locationAvailability); } }; fusedLocationProviderClient .requestLocationUpdates(mLocationRequest, mLocationCallback, Looper.getMainLooper()) .addOnSuccessListener(new OnSuccessListener() { @Override public void onSuccess(Void aVoid) { Log.i(TAG, "request location updates success"); } }) .addOnFailureListener(new OnFailureListener() { @Override public void onFailure(Exception e) { Log.e(TAG, "request location updates failed, error: " + e.getMessage()); } }); }

Kotlin

private fun requestLocationUpdate() { mLocationRequest = LocationRequest() mLocationRequest!!.interval = 5000 mLocationRequest!!.priority = LocationRequest.PRIORITY_HIGH_ACCURACY mLocationCallback = object : LocationCallback() { override fun onLocationResult(locationResult: LocationResult) { super.onLocationResult(locationResult) writeGpsData2Sdcard(locationResult.lastLocation) if (mIsRunning) { processLocationChange(locationResult.lastLocation) } } override fun onLocationAvailability(locationAvailability: LocationAvailability?) { super.onLocationAvailability(locationAvailability) } } fusedLocationProviderClient ?.requestLocationUpdates(mLocationRequest, mLocationCallback, Looper.getMainLooper()) ?.addOnSuccessListener { Log.i(TAG, "request location updates success") } ?.addOnFailureListener { e -> Log.e( TAG, "request location updates failed, error: " + e.message ) } }

当我们不再需要接收位置更新时,应当停止位置更新,以便于降低功耗。要停止位置更新,可以调用removeLocationUpdates(),传入与requestLocationUpdates()接口相对应的LocationCallback。

Java代码

private void removeLocationUpdatesWithCallback() { try { Task voidTask = fusedLocationProviderClient.removeLocationUpdates(mLocationCallback); voidTask.addOnSuccessListener(new OnSuccessListener() { @Override public void onSuccess(Void aVoid) { } }).addOnFailureListener(new OnFailureListener() { @Override public void onFailure(Exception e) { } }); } catch (Exception e) { } }

Kotlin代码

private fun removeLocationUpdatesWithCallback() { try { val voidTask: Task = fusedLocationProviderClient!!.removeLocationUpdates(mLocationCallback) voidTask.addOnSuccessListener { }.addOnFailureListener { } } catch (e: Exception) { } }

在前两个步骤中,我们已经完成了地图服务定位服务的基础功能实现。下面我们将要将两种能力结合起来,实现跑步运动时记录运动轨迹,并计算距离速度的场景。

1. 设置我的位置图层的位置源

在OnMapReady回调中,添加位置源,

JAVA代码

// Add Location Source mHwMap.setLocationSource(new LocationSource() { @Override public void activate(OnLocationChangedListener onLocationChangedListener) { mListener = onLocationChangedListener; } @Override public void deactivate() { } });

Kotlin代码

//Add Location Source mHwMap?.setLocationSource(object : LocationSource { override fun activate(onLocationChangedListener: LocationSource.OnLocationChangedListener?) { mListener = onLocationChangedListener } override fun deactivate() {} }) 2. 获取当前的定位信息,更新Map的镜头

在OnMapReady回调中,添加获取位置信息的代码,并更新Map的镜头位置。

JAVA代码

//Obtains the current position and updates the map camera. try { Task lastLocation = fusedLocationProviderClient.getLastLocation(); lastLocation.addOnSuccessListener(new OnSuccessListener() { @Override public void onSuccess(Location location) { mListener.onLocationChanged(location); if (mListener != null) { mListener.onLocationChanged(location); CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom( new LatLng(location.getLatitude(), location.getLongitude()), 15f); mHwMap.animateCamera(cameraUpdate); } } }).addOnFailureListener(new OnFailureListener() { @Override public void onFailure(Exception e) { } }); } catch (Exception e) { }

Kotlin代码

//Obtains the current position and updates the map camera. try { val lastLocation: Task = fusedLocationProviderClient!!.lastLocation lastLocation.addOnSuccessListener { location -> mListener!!.onLocationChanged(location) if (mListener != null) { mListener!!.onLocationChanged(location) val cameraUpdate: CameraUpdate = CameraUpdateFactory.newLatLngZoom( LatLng(location.latitude, location.longitude), 15f ) mHwMap!!.animateCamera(cameraUpdate) } }.addOnFailureListener { Log.d(TAG, "onMapReady: Obtains the current position failure") } } catch (e: Exception) { }

设置完位置源后,我们就可以在地图上,看见我们的位置了。

3. 添加跑步按钮及开关方法。

我们先添加展示运动数据的布局

再在MapActivity中,添加展示运动数据界面JAVA代码

// Add the exercise data display UI. mTvSpeed = findViewById(R.id.tv_speed); mTvDistance = findViewById(R.id.tv_distance); mTime = findViewById(R.id.cm_time); mTvStart = findViewById(R.id.tv_start); mTvStart.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { processStartClick(); } });

Kotlin代码

// Add the exercise data display UI. mTvSpeed = findViewById(R.id.tv_speed) mTvDistance = findViewById(R.id.tv_distance) mTime = findViewById(R.id.cm_time) mTvStart = findViewById(R.id.tv_start) mTvStart!!.setOnClickListener(View.OnClickListener { processStartClick() })

开始跑步时,在processStartClick()方法中添加以下代码

JAVA代码

mIsRunning = true; mPath.reset(); mPath.setStartTime(System.currentTimeMillis()); mHandler.post(mTimeRunnable); mTvStart.setText("Stop");

Kotlin代码

mIsRunning = true mPath.reset() mPath.startTime = System.currentTimeMillis() mHandler.post(mTimeRunnable) mTvStart!!.text = "Stop"

结束跑步时,在processStartClick()方法中添加以下代码

JAVA代码

mIsRunning = false; mPath.setEndTime(System.currentTimeMillis()); mTvStart.setText("Start"); mHandler.removeCallbacks(mTimeRunnable); if (mPath.getPathLine().size() > 0) { mPath.setEndPoint(mPath.getPathLine().get(mPath.getPathLine().size() - 1)); if (null != mMarkerStart && null != mMarkerEnd) { mMarkerStart.remove(); mMarkerEnd.remove(); } MarkerOptions StartPointOptions = new MarkerOptions() .icon(BitmapDescriptorFactory.fromResource(R.mipmap.map_marker_bubble_azure_small)) .position(mPath.getStartPoint()); StartPointOptions.title("Start Point"); StartPointOptions.snippet("Start Point"); mMarkerStart = mHwMap.addMarker(StartPointOptions); MarkerOptions EndPointOptions = new MarkerOptions() .icon(BitmapDescriptorFactory.fromResource(R.mipmap.map_marker_bubble_azure_small)) .position(mPath.getEndPoint()); EndPointOptions.title("End Point"); EndPointOptions.snippet("End Point"); mMarkerEnd = mHwMap.addMarker(EndPointOptions); }

Kotlin代码

mIsRunning = false mPath.endTime = (System.currentTimeMillis()) mTvStart!!.text = "Start" mHandler.removeCallbacks(mTimeRunnable) if (mPath.mPathLinePoints!!.size > 0) { mPath.endPoint = (mPath.mPathLinePoints!!.get(mPath.mPathLinePoints!!.size - 1)) if (null != mMarkerStart && null != mMarkerEnd) { mMarkerStart!!.remove() mMarkerEnd!!.remove() } val startPointOptions: MarkerOptions = MarkerOptions() .icon(BitmapDescriptorFactory.fromResource(R.mipmap.map_marker_bubble_azure_small)) .position(mPath.mStartPoint) startPointOptions.title("Start Point") startPointOptions.snippet("Start Point") mMarkerStart = mHwMap!!.addMarker(startPointOptions) val endPointOptions: MarkerOptions = MarkerOptions() .icon(BitmapDescriptorFactory.fromResource(R.mipmap.map_marker_bubble_azure_small)) .position(mPath.mEndPoint) endPointOptions.title("End Point") endPointOptions.snippet("End Point") mMarkerEnd = mHwMap!!.addMarker(endPointOptions) }

将processStartClick()方法绑定到"Start"按钮上。

4. 根据当前位置信息变化,绘制运动轨迹

我们创建一个处理方法processLocationChange(Location location)。在这个方法中我们根据位置信息,在地图上绘制折线。JAVA代码

private void processLocationChange(Location location) { LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude()); // Draw a motion track on a map mPolylineOptions.add(latLng); mHwMap.addPolyline(mPolylineOptions); // Updating Map Kit Camera if (mListener != null) { mListener.onLocationChanged(location); CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom( new LatLng(location.getLatitude(), location.getLongitude()), 15f); mHwMap.animateCamera(cameraUpdate); } }

Kotlin代码

private fun processLocationChange(location: Location) { val latLng = LatLng(location.latitude, location.longitude) if (mPath.mStartPoint == null) { mPath.mStartPoint = latLng } mPath.addPoint(latLng) val distance: Float = mPath.updateDistance() val sportMile = distance / 1000.0 if (mSeconds > 0) { val distribution = mSeconds.toDouble() / 60.0 / sportMile mPath.setDistribution(distribution) mTvSpeed!!.text = mDecimalFormat.format(distribution) mTvDistance!!.text = mDecimalFormat.format(sportMile) } else { mPath.setDistribution(0.0) mTvSpeed!!.text = "0.00" mTvDistance!!.text = "0.00" } // Draw a motion track on a map mPolylineOptions!!.add(latLng) mHwMap!!.addPolyline(mPolylineOptions) // Updating Map Kit Camera if (mListener != null) { mListener!!.onLocationChanged(location) val cameraUpdate: CameraUpdate = CameraUpdateFactory.newLatLngZoom( LatLng(location.latitude, location.longitude), 15f ) mHwMap!!.animateCamera(cameraUpdate) } }

在位置更新的回调方法requestLocationUpdate()中,我们调用processLocationChange()方法。JAVA代码

private void requestLocationUpdate() { mLocationCallback = new LocationCallback() { @Override public void onLocationResult(LocationResult locationResult) { super.onLocationResult(locationResult); if (mIsRunning) { processLocationChange(locationResult.getLastLocation()); } } };

Kotlin代码

mLocationCallback = object : LocationCallback() { override fun onLocationResult(locationResult: LocationResult) { super.onLocationResult(locationResult) writeGpsData2Sdcard(locationResult.lastLocation) if (mIsRunning) { processLocationChange(locationResult.lastLocation) } } override fun onLocationAvailability(locationAvailability: LocationAvailability?) { super.onLocationAvailability(locationAvailability) } }

当我们持续获得实时位置更新的时候,就可以绘制运动轨迹了。

华为定位服务提供了模拟定位能力,依托这项能力,我们可以用于应用调试。

1. 打开模拟位置开关

我们需要在测试设备中的开发人员选项中,选择模拟位置信息的应用。

2. 加载模拟GPS数据

我们获取一组模拟GPS数据,本篇Codelab使用的Java GPS数据存放在MockGpsData.java中,Kotlin GPS数据保存在MockGpsData.kt中。在我们创建地图及获取定位之前,加载模拟GPS数据,代码如下:JAVA代码

Task voidTask = fusedLocationProviderClient.setMockMode(true); voidTask.addOnSuccessListener(new OnSuccessListener() { @Override public void onSuccess(Void aVoid) { Toast.makeText(MainActivity.this, "setMockMode onSuccess", Toast.LENGTH_SHORT).show(); mHandler.post(new Runnable() { int point = 0; @Override public void run() { if (point + 1 >= MockGpsData.POINTS.length) { return; } double latitude = MockGpsData.POINTS[point++]; double longitude = MockGpsData.POINTS[point++]; final Location mockLocation = new Location(LocationManager.GPS_PROVIDER); mockLocation.setLongitude(longitude); mockLocation.setLatitude(latitude); Task voidTask = fusedLocationProviderClient.setMockLocation(mockLocation); voidTask.addOnSuccessListener(new OnSuccessListener() { @Override public void onSuccess(Void aVoid) { } }).addOnFailureListener(new OnFailureListener() { @Override public void onFailure(Exception e) { } }); mHandler.postDelayed(this, 100); } }); } }).addOnFailureListener(new OnFailureListener() { @Override public void onFailure(Exception e) { Toast.makeText(MainActivity.this, "setMockMode onFailure:" + e.getMessage(), Toast.LENGTH_SHORT).show(); } });

Kotlin代码

val voidTask: Task = fusedLocationProviderClient!!.setMockMode(true) voidTask.addOnSuccessListener(object : OnSuccessListener { override fun onSuccess(aVoid: Void?) { Toast.makeText(this@MainActivity, "setMockMode onSuccess", Toast.LENGTH_SHORT) .show() mHandler.post(object : Runnable { var point = 0 override fun run() { if (point + 1 >= MockGpsData.POINTS.size) { return } val latitude: Double = MockGpsData.POINTS.get(point++) val longitude: Double = MockGpsData.POINTS.get(point++) val mockLocation = Location(LocationManager.GPS_PROVIDER) mockLocation.longitude = longitude mockLocation.latitude = latitude val voidTask: Task = fusedLocationProviderClient!!.setMockLocation(mockLocation) voidTask.addOnSuccessListener(object : OnSuccessListener { override fun onSuccess(aVoid: Void?) {} }).addOnFailureListener(object : OnFailureListener { override fun onFailure(e: Exception?) {} }) mHandler.postDelayed(this, 100) } }) } }).addOnFailureListener { e -> if (e != null) { Toast.makeText( this@MainActivity, "setMockMode onFailure:" + e.message, Toast.LENGTH_SHORT ).show() } }

加载完成后,我们便可以使用模拟GPS数据进行调试。

干得好,您已经成功完成了Codelab并学到了:

如何在AppGallery Connect上创建应用; 如何开通Location Kit、Map Kit服务; 如何集成地图服务,创建地图; 如何集成定位服务,获取实时定位; 如何绘制运动轨迹; 如何使用模拟定位。 参考文档

您可以阅读下面链接,了解更多相关的信息。

华为定位服务 华为地图服务

您可以点击下方按钮下载源码。

源码下载



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3